package meterMonitor.service;

import meterMonitor.constant.Constant;
import meterMonitor.framework.context.CurrentUser;
import meterMonitor.framework.context.SessionContext;
import meterMonitor.mapper.*;
import meterMonitor.model.*;
import meterMonitor.model.vo.ActivationVO;
import meterMonitor.model.vo.CapacityVO;
import meterMonitor.model.vo.StatusVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class LineService {
    @Autowired
    private LineMapper lineMapper;
    @Autowired
    private DataUpdMapper dataUpdMapper;
    @Autowired
    private AlertMapper alertMapper;
    @Autowired
    private LotnumRecMapper lotnumRecMapper;
    @Autowired
    private ProductivityMapper productivityMapper;

    public void addLine(LinePO line) {
        lineMapper.addLine(line);
    }

    public String updateLine(LinePO line) {
        // if (line.getPeriod() <= 0) {
        //     return "保养天数无法 <= 0 ";
        // }
        lineMapper.updateLine(line);
        return "修改成功";
    }


    public void deleteLine(Integer lineId) {
        lineMapper.deleteLineById(lineId);
    }

    public LinePO getLineById(Integer lineId) {
        return lineMapper.getLineById(lineId);
    }

    public List<LinePO> queryLine(LinePO line) {
        return lineMapper.queryLine(line);
    }

    public List<StatusVO> linesStatus() {
        List<StatusVO> status = new ArrayList<>();
        List<LinePO> lines = lineMapper.queryLine(new LinePO());
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.HOUR_OF_DAY, 8);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.SECOND, 0);
        StatusVO s = null;
        LineRecPO lineRec = null;
        for (LinePO line : lines) {
            s = new StatusVO();
            s.setId(line.getId());
            s.setLineName(line.getName());
            s.setName(line.getName());

            // 查询最新的产线状态
            LineRecPO lastestLineRec = lineMapper.getLastestLineRecByLineId(line.getId());
            if (Objects.nonNull(lastestLineRec)) {
                if (Objects.isNull(lastestLineRec.getEndTime()) || lastestLineRec.getEndTime().getTime() >= instance.getTimeInMillis()) {
                    s.setType(lastestLineRec.getType());
                }
            }

            lineRec = lineMapper.getLineRecByLineIdAndEndTimeIsNull(line.getId());
            if (Objects.nonNull(lineRec)) {
                // 产线开启时间在当天班次开启之前
                if (lineRec.getTime().getTime() <= instance.getTimeInMillis()) {
                    if (lineRec.getType() == 1) {
                        s.setActivation(new BigDecimal(1));
                    } else {
                        s.setActivation(new BigDecimal(0));
                    }
                } else {
                    // 产线开启时间在当天班次开启之后
                    double v1 = (double) (System.currentTimeMillis() - lineRec.getTime().getTime());
                    double v2 = (double) (System.currentTimeMillis() - instance.getTimeInMillis());
                    // 查询所有正常生产的记录
                    List<LineRecPO> lineRecs = lineMapper.getLineRecByLineIdAndType(s.getId(), 1);
                    for (LineRecPO lr : lineRecs) {
                        if (lr.getTime().getTime() < instance.getTimeInMillis()) {
                            v1 += (lr.getEndTime().getTime() - instance.getTimeInMillis());
                        } else {
                            v1 += (lr.getEndTime().getTime() - lr.getTime().getTime());
                        }
                    }
                    double activation = v1 / v2;
                    s.setActivation(new BigDecimal(activation));
                }
            } else {
                // 取最新的一条记录且结束时间不为空
                lineRec = lineMapper.getLineRecByLineIdAndEndTimeNotNull(line.getId());
                // 查询不到记录
                if (Objects.isNull(lineRec)) {
                    s.setActivation(new BigDecimal(0));
                } else {
                    // 结束时间小于早班开始时间
                    if (lineRec.getEndTime().getTime() <= instance.getTimeInMillis()) {
                        s.setActivation(new BigDecimal(0));
                    } else {
                        // 开始时间小于早班时间
                        if (lineRec.getTime().getTime() <= instance.getTimeInMillis()) {
                            if (lineRec.getType() == 1) {
                                double v1 = (double) (lineRec.getEndTime().getTime() - lineRec.getTime().getTime());
                                double v2 = (double) (System.currentTimeMillis() - instance.getTimeInMillis());
                                s.setActivation(new BigDecimal(v1 / v2));
                            } else {
                                s.setActivation(new BigDecimal(0));
                            }
                        } else {
                            // 开始时间大于早班时间、
                            // 查询所有正常生产的记录
                            List<LineRecPO> lineRecs = lineMapper.getLineRecByLineIdAndType(s.getId(), 1);
                            double diff = 0L;
                            for (LineRecPO lineRec2 : lineRecs) {
                                if (lineRec2.getTime().getTime() <= instance.getTimeInMillis()) {
                                    diff += lineRec2.getEndTime().getTime() - instance.getTimeInMillis();
                                } else {
                                    diff += lineRec2.getEndTime().getTime() - lineRec2.getTime().getTime();
                                }
                            }
                            double total = System.currentTimeMillis() - instance.getTimeInMillis();
                            s.setActivation(new BigDecimal(diff / total));
                        }
                    }
                }
            }

            CurrentUser currentUser = SessionContext.getCurrentUser();
            if (currentUser.getRoleId() != Constant.ROLE_GUEST) {
                List<AlertRecPO> alertRecs = alertMapper.getAlertRecByLineId(s.getId());
                for (AlertRecPO alertRec : alertRecs) {
                    if (null == alertRec.getDealedTime()) {
                        s.setType(4); // 报警
                    }
                }
            }

            status.add(s);
        }

        //
        // // 查询是否存在报警信息，并计算每条产线的稼动率
        // for (StatusVO s : status) {
        //     // 计算稼动率
        //
        //     // 停机
        //     List<LineRecPO> lineRecs = lineMapper.getLineRecByLineIdAndType(s.getId(), 1);
        //     // 保养
        //     List<LineRecPO> lineRecs2 = lineMapper.getLineRecByLineIdAndType(s.getId(), 3);
        //
        //     Long total = 0L;
        //     Calendar instance = Calendar.getInstance();
        //     if (instance.get(Calendar.HOUR_OF_DAY) >= 8) {
        //         total = instance.getTimeInMillis() - getStartTime() - 8 * 60 * 60 * 1000L;
        //     } else {
        //         total = instance.getTimeInMillis() - getStartTime() + 16 * 60 * 60 * 1000L;
        //     }
        //
        //     Long diff = 0L;
        //     for (LineRecPO rec : lineRecs) {
        //         if (null == rec.getEndTime()) {
        //             diff += instance.getTimeInMillis() - rec.getTime().getTime();
        //         } else {
        //             diff += rec.getEndTime().getTime() - rec.getTime().getTime();
        //         }
        //     }
        //
        //     // 查询报警记录
        //     // Long alert = 0L;
        //     List<AlertRecPO> alertRecs = alertMapper.getAlertRecByLineId(s.getId());
        //     for (AlertRecPO alertRec : alertRecs) {
        //         if (null == alertRec.getDealedTime()) {
        //             s.setType(4); // 报警
        //         }
        //         // if (null == alertRec.getDealedTime()) {
        //         //     alert += System.currentTimeMillis() - alertRec.getAlTime().getTime();
        //         // } else {
        //         //     alert += alertRec.getDealedTime().getTime() - alertRec.getAlTime().getTime();
        //         // }
        //     }
        //     s.setActivation(new BigDecimal((double) ((diff)) / total));
        // }
        return status;
    }


    private static Long getStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime().getTime();
    }

    public Long countTarget() {
        return lineMapper.countTarget();
    }

    public Long countCapacity() {
        return dataUpdMapper.countCapacity();
    }

    public List<CapacityVO> selectCapacity() {
        List<CapacityVO> capacitys = new ArrayList<>();
        List<LinePO> lines = lineMapper.queryLine(new LinePO());

        for (LinePO line : lines) {
            CapacityVO cap = new CapacityVO();
            cap.setLineName(line.getName());
            DataUpdPO dataUpdPO = dataUpdMapper.selectCapacityByLineId(line.getId());

            BigDecimal binPce = dataUpdMapper.selectBinPce(line.getId());

            if (Objects.isNull(dataUpdPO) || Objects.isNull(dataUpdPO.getDataValue())) {
                cap.setCapacity(new BigDecimal(0));
            } else {
                if (Objects.nonNull(binPce)) {
                    cap.setCapacity(dataUpdPO.getDataValue().subtract(binPce));
                } else {
                    cap.setCapacity(dataUpdPO.getDataValue());
                }
            }

            ProductivityPO productivity = productivityMapper.selectLastestByLineId(line.getId());
            if (Objects.isNull(productivity) || Objects.isNull(productivity.getTarget())) {
                cap.setTarget(new BigDecimal(0));
            } else {
                cap.setTarget(new BigDecimal(productivity.getTarget()));
            }

            capacitys.add(cap);
        }
        return capacitys;
        // return dataUpdMapper.selectCapacity();
    }

    // 配合前端补空数据
    public List<ActivationVO> countActivation() {
        List<ActivationVO> activations = lineMapper.countActivation();
        Set<String> dates = new HashSet<>();
        Set<String> lines = new HashSet<>();
        Map<String, ActivationVO> tmp = new HashMap<>();
        for (ActivationVO ac : activations) {
            String date = ac.getDate();
            dates.add(date);
            lines.add(ac.getLineId() + "_&" + ac.getLineName());
            tmp.put(date + "_&" + ac.getLineId() + "_&" + ac.getLineName(), ac);
        }
        for (String date : dates) {
            for (String line : lines) {
                if (tmp.get(date + "_&" + line) == null) {
                    ActivationVO ac = new ActivationVO();
                    ac.setLineId(Long.parseLong(line.split("_&")[0]));
                    ac.setLineName(line.split("_&")[1]);
                    ac.setDate(date);
                    ac.setValue(new BigDecimal(0));
                    activations.add(ac);
                }
            }
        }
        return activations;
    }

    public List<DataUpdPO> getParameters(Integer lineId) {
        DataUpdPO data = new DataUpdPO();
        data.setLineId(lineId);
        return dataUpdMapper.queryCurrentList(data);
    }

    public List<LotnumRecPO> getProducts(Integer lineId) {
        return lotnumRecMapper.queryCurrentLotnumRecByLineId(lineId);
    }

    public List<AlertRecPO> getAlertInfos(Integer lineId) {
        return alertMapper.getAlertRecByLineId(lineId);
    }
}
